基础

1. 简介

.NET简介

Microsoft新一代多语言的开发平台,用于构建和运行应用程序。

.NET程序开发和运行的环境主要由两部分组成:

  • 公共语言运行时
  • 类库
image-20221105212948262
Image

CLS 公共语言规范 目的:跨语言

  • Common Language Specification.

  • 定义了.NET平台上运行的语言所必须支持的规范,用以避免不同语言特性产生的错误,实现语言间互操作。

CLR 公共语言运行库 目的:优化,跨平台

  • Common Language Runtime.

  • 程序运行环境,负责内存分配、垃圾收集、安全检查等工作。

垃圾回收器

  • GC(Garbage Collection)是CLR中一种针对托管堆自动回收释放内存的服务。
  • GC线程从栈中的引用开始跟踪,从而判定哪些内存是正在使用的,若GC无法跟踪到某一块堆内存,那么就认为这块内存不再使用了,即为可回收的。

编译运行过程

源代码.cs --> CLS编译 --> CIL(通用中间语言)(.exe, .dll) --> CLR编译、申请空间从逻辑上进行划分堆栈等、运行 --> 机器码

通用类型系统CTS(Common Type System)是.NET框架中的一个组成部分,为所有面向.NET框架的语言定义了数据类型的规则。

C#

Microsoft专为.NET推出的高级编程语言。

Mono

Novell 公司支持在其他操作系统下开发.NET 程序的框架。

Unity借助Mono实现跨平台,核心是.NET Framework框架。

2. Hello World

using System;

namespace Day01
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "My First Program";
            // comment
            Console.WriteLine("Hello World!");
            string input = Console.ReadLine();
            Console.WriteLine(input);
        }
    }
}

3. 变量

容量的单位

  • 位bit
  • 字节Byte

整型

  • 1个字节:有符号sbyte (-128~127),无符号byte (0~255).
  • 2个字节:有符号short (-32768~32767),无符号ushort (0~65535).
  • 4个字节:有符号int,无符号uint.
  • 8个字节:有符号long,无符号ulong.

非整型(小数)

  • 4字节:单精度浮点类型float,精度7位。1.2f

  • 8字节:双精度浮点类型double,精度15-16位。1.2d

  • 16字节:128位数据类型decimal,精度28-29位,适用于财务和货币计算。对于精度较高的场合可以使用decimal。1.2m

  • 注意事项:

    1. 非整型变量赋值要加上后缀,如果不加默认为double。

    2. 浮点型运算会出现舍入误差:

      bool number = 1.0f - 0.9f == 0.1f;

非数值型

  • char 字符,2字节,存储单个字符,使用单引号。
  • string 字符串,存储文本,使用双引号。
  • bool类型,1字节,可以直接赋值true 真和false 假,或者赋表达式做判断。

4. 语法

变量命名使用小驼峰。string studentName;

数组的声明方式

int[] arr1 = new int[1];
int[,] arr2 = new int[1,2];

交错数组

列大小不确定的数组。

// 创建具有4个元素的交错数组
int[][] arr = new int[4][];
// 创建一维数组,赋值给交错数组的第i个元素
arr[0] = new int[3];
arr[1] = new int[5];
arr[2] = new int[4];
arr[3] = new int[1];

// 将数字n赋值给交错数组的第i个元素的第j个元素
arr[0][0] = 1;
arr[1][2] = 2;

传递数组的方式

params 参数数组:使用params关键字后,对于方法内部而言,就是个普通数组。对于方法外(调用者)而言,可以传递数组,也快吃传递一组数据类型相同的变量集合,甚至可以不传递参数。

类似Java的可变形参String ... args

int[] arr = new int[]{1, 23, 3, 5};
Add(arr);
Add(1, 23, 3, 5);
Add();

private static int Add(params int[] arr) 
{
  int sum = 0;
  foreach (var item in arr) 
  {
    sum += item;
  }
  return sum;
}

引用传递

传递实参变量自身的内存地址

在传入之前必须赋值

private static void Fun(ref int a, ref int b) {
  int temp = a;
  a = b;
  b = temp;
}

// 需要赋值后才可传入
int a = 1, b = 2;
Fun(ref a, ref b);

输出传递

传递实参变量自身的内存地址

控制离开方法之前必须对out参数进行赋值

private static void Fun(ref int length, ref int width, out int area, out int perimeter) {
  // 方法内部必须为参数赋值
  area = length * width;
  perimeter = (length + width) * 2;
}

int length = 1, width = 2, area, perimeter;
Fun(ref length, ref width, out area, out perimeter);

var类型推断

根据所赋数据判断类型

var v1 = 1;
var v2 = true;

string.Format 字符串格式化

占位符

string str = string.Format("枪的名称为:{0},容量为:{1}", gunName, ammoCapacity);
Console.WriteLine(str);

// c | C:货币格式
// d | D:十进制格式
// e | E:科学计数(指数)格式
// f | F:浮点格式
// x | X:十六进制格式
// p | P: 百分比格式

// $10.00
Console.WriteLine("{0:c}", 10); 

// 05
Console.WriteLine("{0:d2}", 5);

// 以指定精度四舍五入
// 1.2
Console.WriteLine("{0:f1}", 1.23);

// 10.000%
Console.WriteLine("{0:p}", 0.1);

// 空字符表示
char c = '\0';

// \r\n 回车换行
Console.WriteLine("Hello, \r\n world!");

// 从字符串中获取字符
char c1 = str[0];

运算符

// 赋值表达式自身也有值,其值为所赋值
int n1, n2;
n1 = n2 = 1;
// n1 == n2 == 1

类型转换

// Parse转化:string 转化为其他的数据类型
string strNumber = "18";
int num = int.Parse(strNumber);
float num2 = float.Parse(strNumber);

// 任意类型转string
string s1 = num.ToString();

隐式转换和强制转换和Java相同。

4.1. 流程控制

swich-case 中的case有操作,则不支持贯穿到后面的case或default,必须使用break跳出。

if-else if-else, switch, for, while-do, do-while和Java大同小异。

foreach

int[] arr = new int[] { 1, 2, 3, 4 };
foreach(int val in arr)
{
  Console.WriteLine(val);
}

4.2. 方法

方法名首字母大写,采用大驼峰的写法。

返回的数据必须与返回值类型兼容(可以自动隐式转换)。

/// <summary>
/// 根据年月日,计算星期数的方法
/// </summary>
/// <param name="year"></param>
/// <param name="month"></param>
/// <param name="day"></param>
/// <returns></returns>
private static int GetWeekByDay(int year, int month, int day)
{
  DateTime dateTime = new DateTime(year, month, day);
  return (int)dateTime.DayOfWeek;
}

数组常用方法及属性

  • 数组长度:数组名.Length

  • 清除元素值:Array.Clear

  • 复制元素:

    Array.Copy

    数组名.CopyTo

  • 克隆:数组名.Clone

  • 查找元素:

    Array.IndexOf

    Array.LastIndexOf

  • 排序:Array.Sort

  • 反转:Array.Reverse

判断是否为同一个引用

bool flag = object.ReferenceEquals(s1, s2);

4.3. 类

object 是所有类的父类

object o1 = 1;
object o2 = "2";

Array是数组的父类

Array arr1 = new int[2];
Array arr2 = new double[2];

对象

using System;
namespace Main
{
    public class Person
    {
        // 私有字段配置公开属性,类似于Java的Getter和Setter

        // 字段:存储数据
        private string name;

        // 属性:保护字段
        public string Name
        {
            // 本质就是Java中的Getter和Setter
            // 读取时保护
            get
            {
                return name;
            }
            // 写入时保护
            set
            {
                // 用value关键字表示要设置的数据
                this.name = value;
            }
        }
    }
}

简写(.NET3.0):

// 自动属性:包含1个字段 2个方法
public int Age { get; set; }

构造函数

public Person()
{

}

// 在构造函数里面调用其他构造函数
public Person(string name) : this()
{
  this.Name = name;
}

继承

// 继承Person类
public class Student : Person {

}

4.4. 枚举

using System;
namespace Main
{
      // 默认为int,可显式指定
      // public enum MoveDirection : int
    public enum MoveDirection
    {
        UP = 0,
        DOWN = 1,
        LEFT = 2,
        RIGHT = 3,
    }
}

多个枚举值做或运算实现多选,这要求:

  1. 做或运算的结果不能与其他枚举的值相同,即当个只在某一个位上为1,且不与其他枚举相同。

  2. 定义枚举的时候,使用[Flags]修饰。

    [Flags]表示可以将枚举作为位域(即一组标志处理)。

  3. 最后做判断的时候,将传入的值与枚举值逐个做与运算,可得出是否包含该枚举值。

using System;
namespace Main
{
      [Flags]
    public enum MoveDirection
    {
        UP = 0,
        DOWN = 1,
        LEFT = 2,
        RIGHT = 4,
    }
}

// 
move(MoveDirection.UP | MoveDirection.Down);

private static void move(MoveDirection direction)
{
      if ((dorection & MoveDirection.UP) != 0) {
      //...
    }
}

数值类型转换

Print(MoveDirection.Left);

// int <==> enum
// 使用强制类型转换实现
Print((MoveDirection) 2);
int num = (int) MoveDirection.Left;

// string ==> enum
MoveDirection direction = (MoveDirection) Enum.Parse(typeof(MoveDirection), "LEFT");
// enum ==> string
String str = MoveDirection.LEFT.ToString();

4.5. 集合

List是一个类,可以直接new。List根据索引获取元素。

List<string> list = new List<string>();
list.Add("test");
string str = list[0];

字典集合Dictionary(Map)。字典根据key获取元素,用中括号。

Dictionary<string, int> dic = new Dictionary<string, int>();
dic.Add("test", 0);
int i1 = dic["test"];

5. 数据类型

  • 值类型
    • 结构
      • 数值类型
      • bool
      • char
    • 枚举
  • 引用类型
    • 接口
      • string
      • Array
      • 委托

6. IDE

6.1. Visual Studio

region和endregion

其作用是将一段代码标记为给定名称的块,当代码量比较大的时候,可以方便地实现代码的管理。可以将代码折叠,只显示注释。

不属于C#语法。

#region 从字符串中获取字符
  char c2 = str[1];
#endregion

调试步骤

  1. 在可能出错的行加断点。
  2. 按F5 启动调试。
  3. 按F11逐语句执行。
  4. 按Shift + F5 停止调试。

其他

prop + tab = public object MyProperty { get; set; }

Copyright © rootwhois.cn 2021-2022 all right reserved,powered by GitbookFile Modify: 2023-03-05 10:55:52

results matching ""

    No results matching ""